#include "ipc_client.h"

#include <gio/gio.h>
#include <thread>
#include <mutex>

namespace ipc
{	
	// 提前声明创建GDBUS服务的函数
	static void prvPost(Bundle& data);
	static inline Bundle prvSend(Bundle& data);
	static void prvAddServerObserverForId(const std::string& id, IServerObserver* observer);
	static void prvRemoveServerObserverForId(const std::string& id, IServerObserver* observer);
	
	// 客户端名称
	static std::string sClientName;
	
	// 服务连接监听器
	static IServiceConnectionListener* sServiceConnectionListener;
	
	// 防止容器并发(小心递归:Service::Service, prvGetService, prvGetConnection不加锁)
	static std::mutex sMapMutex;
	
	// 服务名称 到 服务器名称 的映射 (创建服务信息对象时可以寻找服务器名称)
	static std::map<std::string, std::string> sServiceToServerMap;
	
	Client* Client::getInstance()
	{
		static Client* instance = new Client();
		return instance;
	}
	
	// 设置客户端名称,让服务器知道是谁发过来的消息
	void Client::setClientName(const std::string& name)
	{
		sClientName = name;
	}
	
	// 设置服务连接监听器
	void Client::setServiceConnectionListener(IServiceConnectionListener* listener)
	{
		sServiceConnectionListener = listener;
	}
	
	// 如果多个服务复用一个服务器，设置了服务的服务器名称后就可以减少进程间的IPC连接
	void Client::setServerNameForService(const std::string& serviceName, const std::string& serverName)
	{
		std::lock_guard<std::mutex> lock(sMapMutex);
		
		sServiceToServerMap[serviceName] = serverName;
	}
	
	// 异步发送数据给服务器
	void Client::post(Bundle& data)
	{
		prvPost(data);
	}
	
	// 同步发送数据给服务器，并接收服务器的返回
	Bundle Client::send(Bundle& data)
	{
		return prvSend(data);
	}
	
	// 监听服务器某id对应的数据
	void Client::addServerObserverForId(const std::string id, IServerObserver* observer)
	{
		prvAddServerObserverForId(id, observer);		
	}
	
	// 不监听服务器某id对应的数据
	void Client::removeServerObserverForId(const std::string id, IServerObserver* observer)
	{
		prvRemoveServerObserverForId(id, observer);
	}	
	
} // namespace ipc



// ----------------------------------------------------------------------------------------------
// 封装函数
// ----------------------------------------------------------------------------------------------
namespace ipc
{
	// 减少函数调用
	static const std::string& KEY_CLIENT	= IpcKit::getKeyClient();
	static const std::string& KEY_ID 		= IpcKit::getKeyId();
	static const std::string& KEY_VALUE		= IpcKit::getKeyValue();
	static const std::string& KEY_OBSERVER	= IpcKit::getKeyObserver();
	static const std::string& EMPTY_STR		= IpcKit::getEmptyStr();
	
	
	// 异步发送基本类型 -------------------------------------------------------------------------
	
	void Client::postInt8(const std::string& id, int8_t value)
	{
		prvPost(Bundle().setString(KEY_ID, id).setInt8(KEY_VALUE, value));
	}
	
	void Client::postInt16(const std::string& id, int16_t value)
	{
		prvPost(Bundle().setString(KEY_ID, id).setInt16(KEY_VALUE, value));
	}
	
	void Client::postInt32(const std::string& id, int32_t value)
	{
		prvPost(Bundle().setString(KEY_ID, id).setInt32(KEY_VALUE, value));
	}
	
	void Client::postInt64(const std::string& id, int64_t value)
	{
		prvPost(Bundle().setString(KEY_ID, id).setInt64(KEY_VALUE, value));
	}
	
	void Client::postFloat(const std::string& id, float value)
	{
		prvPost(Bundle().setString(KEY_ID, id).setFloat(KEY_VALUE, value));
	}
	
	void Client::postDouble(const std::string& id, double value)
	{
		prvPost(Bundle().setString(KEY_ID, id).setDouble(KEY_VALUE, value));
	}
	
	void Client::postString(const std::string& id, const std::string& value)
	{
		prvPost(Bundle().setString(KEY_ID, id).setString(KEY_VALUE, value));
	}
	
			
	// 异步发送基本类型数组 -------------------------------------------------------------
	
	
	void Client::postInt8Vector(const std::string& id, const std::vector<int8_t>& value)
	{
		prvPost(Bundle().setString(KEY_ID, id).setInt8Vector(KEY_VALUE, value));
	}
	
	void Client::postInt16Vector(const std::string& id, const std::vector<int16_t>& value)
	{
		prvPost(Bundle().setString(KEY_ID, id).setInt16Vector(KEY_VALUE, value));
	}
	
	void Client::postInt32Vector(const std::string& id, const std::vector<int32_t>& value)
	{
		prvPost(Bundle().setString(KEY_ID, id).setInt32Vector(KEY_VALUE, value));
	}
	
	void Client::postInt64Vector(const std::string& id, const std::vector<int64_t>& value)
	{
		prvPost(Bundle().setString(KEY_ID, id).setInt64Vector(KEY_VALUE, value));
	}
	
	void Client::postFloatVector(const std::string& id, const std::vector<float>& value)
	{
		prvPost(Bundle().setString(KEY_ID, id).setFloatVector(KEY_VALUE, value));
	}
	
	void Client::postDoubleVector(const std::string& id, const std::vector<double>& value)
	{
		prvPost(Bundle().setString(KEY_ID, id).setDoubleVector(KEY_VALUE, value));
	}
	
	void Client::postStringVector(const std::string& id, const std::vector<std::string>& value)
	{
		prvPost(Bundle().setString(KEY_ID, id).setStringVector(KEY_VALUE, value));
	}
		
	// 异步发送基本类型数组(右值版本, 防止大规模变量拷贝) -------------------------------------------
	
	void Client::postInt8Vector(const std::string& id, std::vector<int8_t>&& value)
	{
		prvPost(Bundle().setString(KEY_ID, id).setInt8Vector(KEY_VALUE, std::move(value)));
	}
	
	void Client::postInt16Vector(const std::string& id, std::vector<int16_t>&& value)
	{
		prvPost(Bundle().setString(KEY_ID, id).setInt16Vector(KEY_VALUE, std::move(value)));
	}
	
	void Client::postInt32Vector(const std::string& id, std::vector<int32_t>&& value)
	{
		prvPost(Bundle().setString(KEY_ID, id).setInt32Vector(KEY_VALUE, std::move(value)));
	}
	
	void Client::postInt64Vector(const std::string& id, std::vector<int64_t>&& value)
	{
		prvPost(Bundle().setString(KEY_ID, id).setInt64Vector(KEY_VALUE, std::move(value)));
	}
	
	void Client::postFloatVector(const std::string& id, std::vector<float>&& value)
	{
		prvPost(Bundle().setString(KEY_ID, id).setFloatVector(KEY_VALUE, std::move(value)));
	}
	
	void Client::postDoubleVector(const std::string& id, std::vector<double>&& value)
	{
		prvPost(Bundle().setString(KEY_ID, id).setDoubleVector(KEY_VALUE, std::move(value)));
	}
	
	void Client::postStringVector(const std::string& id, std::vector<std::string>&& value)
	{
		prvPost(Bundle().setString(KEY_ID, id).setStringVector(KEY_VALUE, std::move(value)));
	}
		

	// 同步发送基本类型
	Bundle Client::sendInt8(const std::string& id, int8_t value)
	{
		return prvSend(Bundle().setString(KEY_ID, id).setInt8(KEY_VALUE, value));
	}
	
	Bundle Client::sendInt16(const std::string& id, int16_t value)
	{
		return prvSend(Bundle().setString(KEY_ID, id).setInt16(KEY_VALUE, value));
	}
	
	Bundle Client::sendInt32(const std::string& id, int32_t value)
	{
		return prvSend(Bundle().setString(KEY_ID, id).setInt32(KEY_VALUE, value));
	}
	
	Bundle Client::sendInt64(const std::string& id, int64_t value)
	{
		return prvSend(Bundle().setString(KEY_ID, id).setInt64(KEY_VALUE, value));
	}
	
	Bundle Client::sendFloat(const std::string& id, float value)
	{
		return prvSend(Bundle().setString(KEY_ID, id).setFloat(KEY_VALUE, value));
	}
	
	Bundle Client::sendDouble(const std::string& id, double value)
	{
		return prvSend(Bundle().setString(KEY_ID, id).setDouble(KEY_VALUE, value));
	}
	
	Bundle Client::sendString(const std::string& id, const std::string& value)
	{
		return prvSend(Bundle().setString(KEY_ID, id).setString(KEY_VALUE, value));
	}
				
	// 同步发送基本类型数组 -------------------------------------------------------------------
	
	Bundle Client::sendInt8Vector(const std::string& id, const std::vector<int8_t>& value)
	{
		return prvSend(Bundle().setString(KEY_ID, id).setInt8Vector(KEY_VALUE, value));
	}
	
	Bundle Client::sendInt16Vector(const std::string& id, const std::vector<int16_t>& value)
	{
		return prvSend(Bundle().setString(KEY_ID, id).setInt16Vector(KEY_VALUE, value));
	}
	
	Bundle Client::sendInt32Vector(const std::string& id, const std::vector<int32_t>& value)
	{
		return prvSend(Bundle().setString(KEY_ID, id).setInt32Vector(KEY_VALUE, value));
	}
	
	Bundle Client::sendInt64Vector(const std::string& id, const std::vector<int64_t>& value)
	{
		return prvSend(Bundle().setString(KEY_ID, id).setInt64Vector(KEY_VALUE, value));
	}
	
	Bundle Client::sendFloatVector(const std::string& id, const std::vector<float>& value)
	{
		return prvSend(Bundle().setString(KEY_ID, id).setFloatVector(KEY_VALUE, value));
	}
	
	Bundle Client::sendDoubleVector(const std::string& id, const std::vector<double>& value)
	{
		return prvSend(Bundle().setString(KEY_ID, id).setDoubleVector(KEY_VALUE, value));
	}
	
	Bundle Client::sendStringVector(const std::string& id, const std::vector<std::string>& value)
	{
		return prvSend(Bundle().setString(KEY_ID, id).setStringVector(KEY_VALUE, value));
	}	
	
	// 同步发送基本类型数组(右值版本, 防止大规模变量拷贝) -----------------------------------------
	
	Bundle Client::sendInt8Vector(const std::string& id, std::vector<int8_t>&& value)
	{
		return prvSend(Bundle().setString(KEY_ID, id).setInt8Vector(KEY_VALUE, std::move(value)));
	}
	
	Bundle Client::sendInt16Vector(const std::string& id, std::vector<int16_t>&& value)
	{
		return prvSend(Bundle().setString(KEY_ID, id).setInt16Vector(KEY_VALUE, std::move(value)));
	}
	
	Bundle Client::sendInt32Vector(const std::string& id, std::vector<int32_t>&& value)
	{
		return prvSend(Bundle().setString(KEY_ID, id).setInt32Vector(KEY_VALUE, std::move(value)));
	}
	
	Bundle Client::sendInt64Vector(const std::string& id, std::vector<int64_t>&& value)
	{
		return prvSend(Bundle().setString(KEY_ID, id).setInt64Vector(KEY_VALUE, std::move(value)));
	}
	
	Bundle Client::sendFloatVector(const std::string& id, std::vector<float>&& value)
	{
		return prvSend(Bundle().setString(KEY_ID, id).setFloatVector(KEY_VALUE, std::move(value)));
	}
	
	Bundle Client::sendDoubleVector(const std::string& id, std::vector<double>&& value)
	{
		return prvSend(Bundle().setString(KEY_ID, id).setDoubleVector(KEY_VALUE, std::move(value)));
	}
	
	Bundle Client::sendStringVector(const std::string& id, std::vector<std::string>&& value)
	{
		return prvSend(Bundle().setString(KEY_ID, id).setStringVector(KEY_VALUE, std::move(value)));
	}	

}	// namespace ipc







// ----------------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------------
// 底层实现(GDBUS, BINDER等)
// ----------------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------------

namespace ipc
{
	// 为连接添加id
	static void prvAddIdForConnection(GDBusConnection* connection, const std::string& id, int64_t observerId);
	
	// 为连接移除id
	static void prvRemoveIdForConnection(GDBusConnection* connection, const std::string& id);
	
	
	// 服务信息(记录服务所在的服务器名成,和服务器的连接，要监听的id)
	class Service
	{
	public:
		Service(const std::string& serviceName) 
			: mServiceName(serviceName)
		{			
			// 服务器的名称
			auto it = sServiceToServerMap.find(serviceName);
			mServerName = ((it != sServiceToServerMap.end()) ? it->second : serviceName);
		}
		
	public:
		// 获取连接(nullptr代表断开连接状态)
		GDBusConnection* getConnection()
		{
			return mConnection;
		}
		
		void setConnection(GDBusConnection* connection);
		
		// 获取服务器名称
		const std::string& getServerName()
		{
			return mServerName;
		}
		
		// 获取监听的id
		std::set<std::string>& getIdSetRef()
		{
			return mIdSet;
		}
		
	private:
		// 服务名称
		std::string mServiceName;
	
		// 服务器名称(除非特别指定，否则服务器名称就是服务名称)
		std::string mServerName;
	
		// 连接
		GDBusConnection* mConnection{nullptr};
		
		// 需要监听的id
		std::set<std::string> mIdSet;
	};	
	
	
	void Service::setConnection(GDBusConnection* connection)
	{
		// 连接上
		if (mConnection == nullptr && connection != nullptr)
		{
			if (sServiceConnectionListener)
			{
				sServiceConnectionListener->onConnected(mServiceName);
			}
			
			// 添加id到连接
			for (auto& id : mIdSet)
			{
				prvAddIdForConnection(connection, id, 0);
			}
		}	
		// 断开
		else if (mConnection != nullptr && connection == nullptr)
		{
			if (sServiceConnectionListener)
			{
				sServiceConnectionListener->onDisconnected(mServiceName);
			}
		}
		mConnection = connection;
	}
	
} // namespace ipc




namespace ipc
{
	// 对象转换 ---------------------------------------------
	
	// 删除Parcel对象
	static void prvDeleteParcel(gpointer data)
	{
		delete ((Parcel*)data);
	}
	
	// 对象转换
	static GVariant* prvToGVariant(const Bundle& bundle)
	{
		// 序列化
		Parcel *parcel = new Parcel;
		bundle.writeToParcel(parcel);
		
		// 创建对象
		return g_variant_new("(@ay)", 
			g_variant_new_from_data(
				G_VARIANT_TYPE_BYTESTRING, 
				parcel->data(), 
				parcel->dataSize(), 
				TRUE, 
				prvDeleteParcel, 
				parcel));
	}	
	
	// 对象转换
	static Bundle prvToBundle(GVariant* parameters)
	{
		Bundle bundle;
		GVariant* data = nullptr;
		g_variant_get(parameters, "(@ay)", &data);
		
		if (data != nullptr)
		{
			// 反序列化
			Parcel parcel(g_variant_get_data(data), g_variant_get_size(data));
			bundle.readFromParcel(&parcel);
		}
		return bundle;
	}
	
} // namespace ipc




namespace ipc
{
	// 服务名->服务
	static std::map<std::string, Service*> sServiceNameToServiceMap;	
	
	// 服务器名 -> 连接
	static std::map<std::string, GDBusConnection*> sServerToConnectionMap;
	
	// id到监听器的映射(回调时,可以找到监听器进行回调)
	static std::map<std::string, std::set<IServerObserver*>> sIdToObserverSetMap;
		
	
	// 连接与回调 -------------------------------------------------------------------
			
	// 服务器回调
	static void prvOnCallback(GDBusConnection* connection,
		const gchar* sender, const gchar* object_path, const gchar*	interface_name,
		const gchar* methodName,
		GVariant* parameters, GDBusMethodInvocation* invocation, gpointer user_data)
	{
		// g_print("prvOnCallback %s\n", methodName);
		
		Bundle data = prvToBundle(parameters);
		
		std::string id = data.getString(KEY_ID, EMPTY_STR);		
		int64_t observerId = data.getInt64(KEY_OBSERVER);
		
		std::set<IServerObserver*> observerSetCopy;		
		{
			std::lock_guard<std::mutex> lock(sMapMutex);
			auto it = sIdToObserverSetMap.find(id);
			// 没人监听这个id
			if (it == sIdToObserverSetMap.end())
			{
				return;
			}
			observerSetCopy = it->second;
		}
		
		// 每一个observer
		if (observerId == 0)
		{
			for (auto& observer : observerSetCopy)
			{
				observer->onUpdate(data);
			}
		}
		// 指定的observer
		else
		{
			if (observerSetCopy.find((IServerObserver*)observerId) != observerSetCopy.end())
			{
				((IServerObserver*)observerId)->onUpdate(data);
			}
		}
	}
	
	
	// 连接被关闭
	static void prvOnConnectionClosed(GDBusConnection* connection, gboolean remote_peer_vanished, GError* error, gpointer ud)
	{
		g_print("connection_closed\n");
		
		std::lock_guard<std::mutex> lock(sMapMutex);
		
		for (auto& kv : sServiceNameToServiceMap)
		{
			// 使用了该连接的服务都设置为nullptr
			if (kv.second->getConnection() == connection)
			{
				kv.second->setConnection(nullptr);
			}
		}
		
		for (auto it = sServerToConnectionMap.begin(); it != sServerToConnectionMap.end(); it++)
		{
			// 移除 服务器名称 -> 连接 的映射
			if (it->second == connection)
			{
				sServerToConnectionMap.erase(it);
				break;
			}
		}
		
		// 取消引用
		g_object_unref(connection);
	}
	
	// 创建连接
	static GDBusConnection* prvNewConnection(const std::string& serverName)
	{
		// 地址
		std::string address = "unix:abstract=";
		address += serverName;

		// 错误信息
		GError* error = NULL;

		GDBusConnection* connection = g_dbus_connection_new_for_address_sync(
			address.c_str(),
			G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
			NULL, NULL, &error);

		// 连接失败
		if (connection == NULL) {
			// 打印连接失败原因
			g_printerr("Error connecting to D-Bus address %s: %s\n", address.c_str(), error->message);
			g_error_free(error);
		}

		// 节点信息
		static const gchar NODE_INFO[] =
			"<node>"
			"  <interface name='com.car.ipc.Channel'>"
			"    <method name='post'>"
			"      <arg type='ay' name='data' direction='in'/>"
			"    </method>"
			"  </interface>"
			"</node>";
		static GDBusNodeInfo* sNodeInfo = g_dbus_node_info_new_for_xml(NODE_INFO, NULL);
		
		static const GDBusInterfaceVTable INTERFACE_VTABLE =
		{
			prvOnCallback,
			NULL,
			NULL,
		};
		
		// 监听断开连接
		g_signal_connect(connection, "closed", G_CALLBACK(prvOnConnectionClosed), NULL);

		// 注册接口虚表
		g_dbus_connection_register_object(
			connection,
			"/com/car/ipc/Channel",
			sNodeInfo->interfaces[0],
			&INTERFACE_VTABLE,
			NULL, 	/* user_data */
			NULL, 	/* user_data_free_func */
			NULL	/* GError */
		);

		return connection;
	}
	
	// 获取连接（retryCnt == 0代表连接一次，失败不重试，1代表失败后重试1次)
	static GDBusConnection* prvGetConnection(Service* service, int retryCnt)
	{
		GDBusConnection* connection = service->getConnection();
		if (connection)
		{
			return connection;
		}
				
		auto it = sServerToConnectionMap.find(service->getServerName());
		// 其他服务已经存在了该连接， 复用
		if (it != sServerToConnectionMap.end())
		{
			service->setConnection(it->second);
			return it->second;
		}		
		
		// 连接服务器
		while (retryCnt-- >= 0)
		{
			GDBusConnection* connection = prvNewConnection(service->getServerName());
			if (connection != nullptr)
			{
				service->setConnection(connection);
				sServerToConnectionMap[service->getServerName()] = connection;
				return connection;
			}
			
			if (retryCnt >= 0) 
			{
				std::this_thread::sleep_for(std::chrono::milliseconds(200));
			}
		}		
		return nullptr;
	}
	
	// 查询服务
	static Service* prvGetService(const std::string& serviceName)
	{
		Service* service = nullptr;
		auto it = sServiceNameToServiceMap.find(serviceName);
		if (it == sServiceNameToServiceMap.end())
		{
			service = new Service(serviceName);
			sServiceNameToServiceMap[serviceName] = service;
		}
		else
		{
			service = it->second;
		}
		return service;
	}
	
	
	
	// ---------------------------------------------------------------------------------
	
	
	// 为连接添加id
	static void prvAddIdForConnection(GDBusConnection* connection, const std::string& id, int64_t observerId)
	{
		g_dbus_connection_call(connection,
			NULL, "/com/car/ipc/Channel", "com.car.ipc.Channel", "add_id",
			g_variant_new("(@(sx))", g_variant_new("(sx)", id.c_str(), observerId)), NULL,
			G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
	}

	// 为连接移除id
	static void prvRemoveIdForConnection(GDBusConnection* connection, const std::string& id)
	{
		g_dbus_connection_call(connection,
			NULL, "/com/car/ipc/Channel", "com.car.ipc.Channel", "remove_id",
			g_variant_new("(s)", id.c_str()), NULL,
			G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
	}
	
	
	// ---------------------------------------------------------------------------------
	
	static void prvPost(Bundle& data)
	{
		// 1. data -> serviceName		
		std::string serviceName = IpcKit::getServiceNameFromId(IpcKit::getId(data));		
		if (!serviceName.empty())
		{
			std::lock_guard<std::mutex> lock(sMapMutex);			
			GDBusConnection* connection = prvGetConnection(prvGetService(serviceName), 3);
			if (connection)
			{
				// 附加客户端名称作为调试信息
				if (!sClientName.empty())
				{
					data.setString(KEY_CLIENT, sClientName);
				}
				g_dbus_connection_call(connection,
					NULL, "/com/car/ipc/Channel", "com.car.ipc.Channel", "post",
					prvToGVariant(data), NULL,
					G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
			}
			// TODO. 是否要确保消息一定要发送成功为止
		}
	}
	
	static inline Bundle prvSend(Bundle& data)
	{
		// 1. data -> serviceName
		std::string serviceName = IpcKit::getServiceNameFromId(IpcKit::getId(data));		
		if (!serviceName.empty())
		{
			std::lock_guard<std::mutex> lock(sMapMutex);
			GDBusConnection* connection = prvGetConnection(prvGetService(serviceName), 3);
			if (connection)
			{
				// 附加客户端名称作为调试信息
				if (!sClientName.empty())
				{
					data.setString(KEY_CLIENT, sClientName);
				}
				GVariant* parameters = g_dbus_connection_call_sync(connection,
					NULL, "/com/car/ipc/Channel", "com.car.ipc.Channel", "send",
					prvToGVariant(data), G_VARIANT_TYPE("(ay)"),
					G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL);
				Bundle ret = prvToBundle(parameters);
				g_variant_unref(parameters);
				return ret;
			}
			// TODO. 是否要确保消息一定要发送成功为止
		}
		return Bundle::getEmpty();
	}
	
	// 监听服务器某id对应的数据
	static void prvAddServerObserverForId(const std::string& id, IServerObserver* observer)
	{
		std::string serviceName = IpcKit::getServiceNameFromId(id);		
		if (!serviceName.empty())
		{
			
			std::lock_guard<std::mutex> lock(sMapMutex);
			
			Service* service = prvGetService(serviceName);
			auto it = sIdToObserverSetMap.find(id);
			// 此id还没被监听
			if (it == sIdToObserverSetMap.end())
			{
				sIdToObserverSetMap[id].insert(observer);
				service->getIdSetRef().insert(id);
			}
			// 此监听器还没和此id关联
			else if (it->second.find(observer) == it->second.end())
			{
				it->second.insert(observer);
			}
			
			// 让服务端回调
			GDBusConnection* connection = service->getConnection();
			if (connection) 
			{
				prvAddIdForConnection(connection, id, (int64_t)observer);
			}
			// 如果此处没有连接也不用担心， 定时器会检查并自动连接
		}
	}
	
	
	static class AutoRun
	{
	public:
		AutoRun()
		{	
			std::thread(checkLoop).detach();
		}
		
	private:
		// 检查并自动连接
		static void checkLoop()
		{
			while (1)
			{
				Service* service = nullptr;				
				{
					std::lock_guard<std::mutex> lock(sMapMutex);
					for (auto& kv : sServiceNameToServiceMap)
					{
						// 使用了该连接的服务都设置为nullptr
						if (kv.second->getConnection() == nullptr && !kv.second->getIdSetRef().empty())
						{
							service = kv.second;
							break;
						}
					}
				}
				
				if (service)
				{
					std::lock_guard<std::mutex> lock(sMapMutex);
					prvGetConnection(service, 0);
					continue;
				}
				std::this_thread::sleep_for(std::chrono::milliseconds(200));
			}
		}
	} sAutoRun;
	
	// 不监听服务器某id对应的数据
	static void prvRemoveServerObserverForId(const std::string& id, IServerObserver* observer)
	{
		std::string serviceName = IpcKit::getServiceNameFromId(id);
		if (serviceName.empty())
		{
			return;
		}
		
		std::lock_guard<std::mutex> lock(sMapMutex);
		
		auto it = sIdToObserverSetMap.find(id);
		// 没有监听器
		if (it == sIdToObserverSetMap.end())
		{
			return;
		}
		auto& observerSet = it->second;
		auto observerIt = observerSet.find(observer);
		// 没有此监听器
		if (observerIt == observerSet.end())			
		{
			return;
		}
		observerSet.erase(observerIt);
		// 移除了全部监听器
		if (observerSet.empty())
		{
			sIdToObserverSetMap.erase(it);
			Service* service = prvGetService(serviceName);
			service->getIdSetRef().erase(id);
			
			// 服务端取消关联
			GDBusConnection* connection = service->getConnection();
			if (connection) 
			{
				prvRemoveIdForConnection(connection, id);
			}
		}
	}
	
	
}	// namespace ipc




